//二：原生js写法

//1 swiper core version + navigation, pagination modules:
import Swiper from 'swiper';
import { Pagination } from 'swiper/modules';

// bootstrap 按需导入 Offcanvas
import { Offcanvas, Tooltip, Modal } from 'bootstrap';

document.addEventListener('DOMContentLoaded', () => {
    console.log('swiper 已加载！');
    // swiper
    const swiper = new Swiper('#productSwiper', {
        // Optional parameters
        modules: [Pagination],//不加这儿，下面的pagination显示不出来
        direction: 'horizontal',//horizontal|vertical
        loop: true,

        // If we need pagination
        pagination: {
            el: '.swiper-pagination',
            type: 'fraction',
            currentClass: 'swiper-pagination-current', // 自定义当前页码的类名 custom-current
            totalClass: 'swiper-pagination-total',     // 自定义总页数的类名 custom-total
            renderFraction: function (currentClass, totalClass) {
                return '<span class="' + currentClass + '">' + '</span> / <span class="' + totalClass + '">' + '</span>';
            },
        },

        // pagination: {
        //     el: '.swiper-pagination',
        //     type: 'custom',
        //     renderCustom: function (swiper, current, total) {
        //         // current 是当前索引（从 1 开始），total 是总页数
        //         return `${current} / ${total}`;
        //     },
        // },

        // // Navigation arrows
        // navigation: {
        //   nextEl: '.swiper-button-next',
        //   prevEl: '.swiper-button-prev',
        // },

        // // And if we need scrollbar
        // scrollbar: {
        //   el: '.swiper-scrollbar',
        // },
    });
});



const $attr_options = ["color", "size"];
const $product_price = { "symbol": "$", "currency": "USD", "value": 99.00 };
const $size_charts = { "size": { "us2": [{ "cm": "83", "inch": "32.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "65", "inch": "25.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "91", "inch": "35.75", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "147", "inch": "58", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "160", "inch": "63", "ft": "5'3\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us4": [{ "cm": "85", "inch": "33.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "68", "inch": "26.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "92", "inch": "36.75", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "147", "inch": "58", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "160", "inch": "65", "ft": "5'5\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us6": [{ "cm": "88", "inch": "34.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "70", "inch": "27.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "96", "inch": "37.75", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "150", "inch": "59", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "165", "inch": "65", "ft": "5'5\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us8": [{ "cm": "90", "inch": "35.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "72", "inch": "28.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "98", "inch": "38.75", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "150", "inch": "59", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "165", "inch": "65", "ft": "5'5\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us10": [{ "cm": "93", "inch": "36.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "75", "inch": "29.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "101", "inch": "39.75", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "152", "inch": "60", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "170", "inch": "67", "ft": "5'7\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us12": [{ "cm": "97", "inch": "38", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "79", "inch": "31", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "105", "inch": "41.25", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "152", "inch": "60", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "170", "inch": "67", "ft": "5'7\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us14": [{ "cm": "100", "inch": "39.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "83", "inch": "32.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "109", "inch": "42.75", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "155", "inch": "61", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "175", "inch": "69", "ft": "5'9\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us16": [{ "cm": "104", "inch": "41", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "86", "inch": "34", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "112", "inch": "44.25", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "155", "inch": "61", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "175", "inch": "69", "ft": "5'9\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us14w": [{ "cm": "104", "inch": "41", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "86", "inch": "34", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "110", "inch": "43.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "155", "inch": "61", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "175", "inch": "69", "ft": "5'9\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us16w": [{ "cm": "109", "inch": "43", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "92", "inch": "36.25", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "116", "inch": "45.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "155", "inch": "61", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "175", "inch": "69", "ft": "5'9\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us18w": [{ "cm": "114", "inch": "45", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "98", "inch": "38.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "121", "inch": "47.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "155", "inch": "61", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "175", "inch": "69", "ft": "5'9\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us20w": [{ "cm": "119", "inch": "47", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "104", "inch": "40.75", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "126", "inch": "49.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "155", "inch": "61", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "175", "inch": "69", "ft": "5'9\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us22w": [{ "cm": "124", "inch": "49", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "109", "inch": "43", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "131", "inch": "51.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "155", "inch": "61", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "175", "inch": "69", "ft": "5'9\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us24w": [{ "cm": "130", "inch": "51", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "115", "inch": "45.25", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "136", "inch": "53.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "155", "inch": "61", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "175", "inch": "69", "ft": "5'9\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }], "us26w": [{ "cm": "135", "inch": "53", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "bust", "attr_name": "Bust" }, { "cm": "121", "inch": "47.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "waist", "attr_name": "Waist" }, { "cm": "141", "inch": "55.5", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hips", "attr_name": "Hips" }, { "cm": "155", "inch": "61", "ft": "", "extensions": [], "size_chart_id": "1", "point_code": "hollowtofloor", "attr_name": "Hollow to Floor" }, { "cm": "175", "inch": "69", "ft": "5'9\"", "extensions": [], "size_chart_id": "1", "point_code": "height", "attr_name": "Height(Bare Foot)" }] } };
const $size_custom_image = { "waist": { "local_img_title": "Waist", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-trouser-waist.jpg.webp", "local_img_desc": "\u2022 Measure around your waist at the level where you would normally wear your pant's belt.<br \/>\n\u2022 With the tape measure snug around your waist, relax, and take the measurement.<br \/>\n\u2022 Don't be alarmed if this measurement seems larger than expected; off-the-rack pants are normally labeled as being smaller than what they really are.<br \/>" }, "shoulder": { "local_img_title": "Shoulder", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-full-shoulder-width.jpg.webp", "local_img_desc": "\u2022 Measure from the end of the right shoulder to the end of the left shoulder.<br \/>\n\u2022 We define the \"End of the Shoulder\" as where the horizontal plane of the shoulder intersects the vertical plane of the arm (see illustration).<br \/>\n\u2022 Double check measurement.<br \/>" }, "bicep": { "local_img_title": "Bicep", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-bicep.jpg.webp", "local_img_desc": "\u2022 Measure around the fullest part of the bicep with the arms by your side.<br \/>\n\u2022 You need only measure one side.<br \/>" }, "wrist": { "local_img_title": "Wrist", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-wrist.jpg.webp", "local_img_desc": "\u2022 Measure around the fullest part of the wrist.<br \/>\n\u2022 You need only measure one side.<br \/>" }, "hips": { "local_img_title": "Hips", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-hips-or-seat.jpg.webp", "local_img_desc": "\u2022 Measure around the fullest part of your hips and buttocks.<br \/>" }, "chest": { "local_img_title": "Chest", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-full-chest.jpg.webp", "local_img_desc": "\u2022 Measure around the chest and body at its fullest part (typically right under the armpits and shoulder blades, right across the nipples).<br \/>\n\u2022 Hold the tape against the body tight enough so that it does not slip down, but not so tight that it restricts breathing. It should be \"snug\".<br \/>\n\u2022 Make sure the tape is horizontal and the person's arms are by their side; then take a normal breath and measure.<br \/>\n\u2022 Do not puff out your chest.<br \/>\n\u2022 Double check this measurement.<br \/>" }, "crotch": { "local_img_title": "Crotch", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-crotch.jpg.webp", "local_img_desc": "\u2022 Measure from the front top of the pant's waistband to the back top of the pant's waistband.<br \/>\n\u2022 Make sure not to take this measurement too tight.<br \/>" }, "stomach": { "local_img_title": "Stomach", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-waist-or-stomach.jpg.webp", "local_img_desc": "\u2022 Measure around the fullest part of the waist\/stomach or right below your bottom ribs, whichever is greater.<br \/>" }, "sleevelength": { "local_img_title": "Sleeve Length", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-sleeve.jpg.webp", "local_img_desc": "\u2022 Measure from the end of either shoulder to the pinch of the corresponding hand.<br \/>\n\u2022 The \"Pinch\" of the hand is found where the base of the thumb and the base of the index finger intersect (approximately 1 inch above the index finger knuckle).<br \/>\n\u2022 Double check this measurement.<br \/>" }, "thigh": { "local_img_title": "Thigh", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-thigh.jpg.webp", "local_img_desc": "\u2022 Measure around your thigh at its widest point.<br \/>\n\u2022 You need measure only one side.<br \/>" }, "knee": { "local_img_title": "Knee", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-knee.jpg.webp", "local_img_desc": "\u2022 Measure around your knee at its widest point.<br \/>\n\u2022 You need only measure one side.<br \/>" }, "length": { "local_img_title": "Length", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-trousers-outseam.jpg.webp", "local_img_desc": "\u2022 Measure from the top of your pant's waistband to the floor along the outside of your leg.<br \/>\n\u2022 Make sure the tape is tight, that you are standing straight, and then measure. No shoes please!<br \/>\n\u2022 Double check this measurement.<br \/>" }, "jacketfrontlength": { "local_img_title": "Front Length", "local_img": "https:\/\/img.luvdress.com\/custom\/men-suits-measure-front-jacket-length.jpg.webp", "local_img_desc": "\u2022 Measure straight down the front from the base of the neck (right or left side) to the point level with your thumb knuckle.<br \/>" }, "height": { "local_img_title": "Height(Bare Foot)", "local_img": "", "local_img_desc": "\u2022 Measure barefoot from floor to top of head.<br \/>\n\u2022 Stand straight against a wall, heels together.<br \/>\n\u2022 Format examples: 5'9\", 5ft9in, 69in (inches) or 175cm (centimeters).<br \/>" }, "weight": { "local_img_title": "Weight", "local_img": "", "local_img_desc": "" } };

const product_info = {};
const symbol = $product_price.symbol;
const originalPrice = $product_price.value;
let totalPrice = 0;

function scrollToElement(ele, headerHeight = 60) {
    const targetElement = document.querySelector(ele);
    if (!targetElement) return;

    const targetOffsetTop = targetElement.getBoundingClientRect().top + window.pageYOffset - headerHeight;

    // 使用原生JavaScript实现平滑滚动
    window.scrollTo({
        top: targetOffsetTop,
        behavior: 'smooth'
    });

    // 如果需要更精细控制，可以使用以下方式实现自定义缓动
    /*
    let start = null;
    const startPosition = window.pageYOffset;
    const distance = targetOffsetTop - startPosition;
    const duration = 300; // ms

    function step(timestamp) {
        if (!start) start = timestamp;
        const progress = timestamp - start;
        const percentage = Math.min(progress / duration, 1);
        window.scrollTo(0, startPosition + distance * easeInOutQuad(percentage));
        if (progress < duration) {
            requestAnimationFrame(step);
        }
    }

    function easeInOutQuad(t) {
        return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
    }

    requestAnimationFrame(step);
    */

    // 示例调用
    // scrollToElement('#color-list');
}
function checkCustomInfo(input) {
    // input.hasAttribute('required')
    const value = input.value.trim();
    if (input.required && input.value === '') {
        input.classList.add('is-invalid');
        // input.nextElementSibling.textContent = `${input.getAttribute('data-measurements-name')} is required.`; // 显示错误信息
        return false;
    } else if (!isNaN(value) && parseFloat(value) <= 0) {
        input.classList.add('is-invalid');
        // input.nextElementSibling.textContent = `${input.getAttribute('data-measurements-name')} must be a positive number.`; // 显示错误信息
        return false;
    } else {
        input.classList.remove('is-invalid');
        return true;
    }
}
/**
 * 获取添加到购物车的数据
 * @returns {Object}
 */
function getCartData() {
    let errors = [];
    let cartData = {}; // 初始化一个空对象

    let $selected_attr_list = [];
    let $selected_size_charts = {};

    const spu_input = document.querySelectorAll('.sku-list-input-js');
    spu_input.forEach(input => {
        const is_customed = input.getAttribute('data-is-custom') === '1';
        //非定制的正常计算
        if (!is_customed) {
            const attr_code = input.name;
            const value_code = input.value;

            if (value_code === '') {
                errors.push(`#${attr_code}-list`);
                document.getElementById(`${attr_code}-error`).classList.remove('d-none');
            }
            $selected_attr_list.push({
                attr_code: attr_code,
                value_code: value_code,
                attr_name: input.getAttribute('data-attr-name'),
                value_name: input.getAttribute('data-selected-value-name'),
                value_price: input.getAttribute('data-selected-value-price'),
                base_value_price: input.getAttribute('data-selected-base-value-price')
            });
            if ($size_charts.hasOwnProperty(attr_code) && $size_charts[attr_code].hasOwnProperty(value_code)) {
                $selected_size_charts[attr_code] = $size_charts[attr_code][value_code];
            }
        }
    });
    cartData['spu_attr'] = $selected_attr_list;
    cartData['size_chart'] = $selected_size_charts;

    // 定制属性
    let $custom_list = [];
    const spu_custom = document.querySelectorAll('.spu_custom_js');
    spu_custom.forEach(input => {
        //如果checked
        if (input.checked) {
            const attr_code = input.getAttribute('data-related-attr-code');
            const size_system = document.getElementById(`${attr_code}-unit-system`).value;

            let size_unit;
            if (size_system == 'imperial') {
                size_unit = 'inch';
            } else {
                size_unit = 'cm';
            }
            // 1 特殊的测量点处理,身高和体重
            const imperialHeight = document.getElementById('imperial-height');//
            const metricHeight = document.getElementById('metric-height');

            const weightUnitLabel = document.getElementById('weight-unit-label');
            // 2 通用的测量点处理
            const customElement = document.getElementById(`${attr_code}-custom-form-container`);
            const cus_units = customElement.querySelectorAll('.custom-input-js');
            // console.log(cus_units);

            let $custom_list_one = {
                attr_code: attr_code,
                attr_name: input.getAttribute('data-related-attr-name'),
                custom_price: input.getAttribute('data-custom-price'),
                base_custom_price: input.getAttribute('data-base-custom-price'),
                size_unit: size_unit,
                list: []
            };

            //如果有身高
            if (imperialHeight) {

                // 计算单位
                let height, current_size_unit, value_with_unit;
                if (size_system == 'imperial') {
                    const feet_input = document.getElementById('feet');
                    const feet = feet_input.value;
                    const inches = document.getElementById('inches').value;
                    height = feet + '\'' + inches + '"';
                    current_size_unit = 'ft';
                    value_with_unit = height;

                    // 检查数据是否正确
                    if (!checkCustomInfo(feet_input)) {
                        errors.push(`#${attr_code}-custom-form-container`);
                    }

                } else {
                    const height_input = document.getElementById('cm');
                    height = height_input.value;
                    current_size_unit = 'cm';
                    value_with_unit = height + current_size_unit;

                    // 检查数据是否正确
                    if (!checkCustomInfo(height_input)) {
                        errors.push(`#${attr_code}-custom-form-container`);
                    }
                }

                // 添加数据
                $custom_list_one.list.push({
                    measurements_code: imperialHeight.getAttribute('data-measurements-code'),
                    measurements_name: imperialHeight.getAttribute('data-measurements-name'),
                    value: height,
                    size_unit: current_size_unit,
                    value_with_unit: value_with_unit
                });
                // console.log('$custom_list_one.list', $custom_list_one.list);
            }
            //如果有体重
            if (weightUnitLabel) {
                // 检查数据是否正确
                const weight_input = document.getElementById('weight');
                if (!checkCustomInfo(weight_input)) {
                    errors.push(`#${attr_code}-custom-form-container`);
                }
                // 计算单位
                let current_size_unit;
                if (size_system == 'imperial') {
                    current_size_unit = 'lb';
                } else {
                    current_size_unit = 'kg';
                }
                // 添加数据
                const weight = weight_input.value;
                $custom_list_one.list.push({
                    measurements_code: weight_input.name,
                    measurements_name: weight_input.getAttribute('data-measurements-name'),
                    value: weight,
                    size_unit: current_size_unit,
                    value_with_unit: weight + ' ' + current_size_unit
                });
            }
            //通用的测量点处理
            cus_units.forEach(cus_unit => {
                // 检查数据是否正确
                if (!checkCustomInfo(cus_unit)) {
                    errors.push(`#${attr_code}-custom-form-container`);
                }
                // 计算单位
                let current_size_unit;
                if (size_system == 'imperial') {
                    current_size_unit = 'in';
                } else {
                    current_size_unit = 'cm';
                }
                // 添加数据
                const value = cus_unit.value;
                $custom_list_one.list.push({
                    measurements_code: cus_unit.name,
                    measurements_name: cus_unit.getAttribute('data-measurements-name'),
                    value: value,
                    size_unit: current_size_unit,
                    value_with_unit: value + ' ' + current_size_unit
                });
            });

            //
            $custom_list.push($custom_list_one);
        }

    });

    cartData['custom_attr'] = $custom_list;

    console.log('cartData:', cartData);
    return {
        errors: errors,
        data: cartData
    }
}
/**
 * 动态更新价格显示
 */
const updatePriceDisplay = () => {
    // totalPrice = originalPrice + additionalCost;
    // document.getElementById('total-price').textContent = `${symbol}${totalPrice.toFixed(2)}`;
    totalPrice = originalPrice;
    const spu_input = document.querySelectorAll('.sku-list-input-js');
    spu_input.forEach(input => {
        const is_customed = input.getAttribute('data-is-custom') === '1';
        //非定制的正常计算
        if (!is_customed) {
            const spu_price = parseFloat(input.getAttribute('data-selected-value-price')) || 0;
            totalPrice += spu_price;
        }
    });
    // 定制属性
    const spu_custom = document.querySelectorAll('.spu_custom_js');
    spu_custom.forEach(input => {
        //如果checked
        if (input.checked) {
            const spu_custom_price = parseFloat(input.getAttribute('data-custom-price')) || 0;
            totalPrice += spu_custom_price;
        }
    });
    document.getElementById('total-price').textContent = `${symbol}${totalPrice.toFixed(2)}`;
};
const parseHeight = (heightStr) => {
    // 使用正则表达式提取英尺和英寸部分
    const match = heightStr.match(/^(\d+)'?(\d*)"?$/);
    if (!match) {
        throw new Error("Invalid height format. Expected format like '5'6 or 5'6\"");
    }
    const feet = parseInt(match[1], 10) || 0;
    const inches = parseInt(match[2], 10) || 0;
    return { feet, inches };
}
//初始化定制表单
const initCustomize = (related_attr, size_system, attr_value) => {

    let size_unit;
    if (size_system == 'imperial') {
        size_unit = 'inch';
    } else {
        size_unit = 'cm';
    }
    //取数据
    let selected_attr = {};
    let point_code;
    for (var i = 0; i < $size_charts[related_attr][attr_value].length; i++) {
        point_code = $size_charts[related_attr][attr_value][i]['point_code'];
        if (point_code == 'height') {
            if (size_unit == 'inch') {
                // 将 ft 转换为 feet 和 inches
                const { feet, inches } = parseHeight($size_charts[related_attr][attr_value][i]['ft']);
                document.getElementById('feet').value = feet;
                document.getElementById('inches').value = inches;
                // 直接输出 5'6"
                // selected_attr[point_code] = $size_charts[related_attr][attr_value][i]['ft'];                
            } else {
                document.getElementById('cm').value = $size_charts[related_attr][attr_value][i][size_unit];
            }
        } else {
            selected_attr[point_code] = $size_charts[related_attr][attr_value][i][size_unit];
        }
    }
    // console.log('selected_attr:', selected_attr);
    // 渲染表单
    const input = document.querySelectorAll(`#${related_attr}-custom-form-container input.custom-input-js`);
    input.forEach(function (el) {
        var name = el.getAttribute('name');
        if (selected_attr[name]) {
            el.value = selected_attr[name];
        }
    });
}
function handleOptionClick(option) {
    // ### 父级的父级 获取属性类型 color size etc.
    // const attrElement = option.closest('li').closest('ul');
    const attrElement = option.closest('ul');
    const attrCode = attrElement.getAttribute('data-attr-code');//color size etc.
    console.log('attrCode:', attrCode);
    if (!$attr_options.includes(attrCode)) return; // 确保是支持的操作类型

    const attrShowSizeChart = attrElement.getAttribute('data-show-size-chart');
    const attrIncreasePrice = attrElement.getAttribute('data-increase-price');

    const valueType = option.getAttribute('data-value-type'); // 获取操作类型（img 或 html 或 txt）

    // ### 选中状态切换
    // 1 找到同类型的其他选项并移除选中状态
    const options = attrElement.querySelectorAll('.option');
    options.forEach(opt => {
        opt.setAttribute('aria-pressed', 'false');
    });
    // 2 设置当前选项为选中状态
    option.setAttribute('aria-pressed', 'true');

    // ### 记录当前选中值到隐藏输入框
    const inputElement = document.getElementById(`${attrCode}-input`);
    inputElement.value = option.getAttribute('data-value-code');
    inputElement.setAttribute('data-selected-value-name', option.getAttribute('data-value-name'));
    inputElement.setAttribute('data-selected-base-value-price', option.getAttribute('data-base-price-increase'));
    inputElement.setAttribute('data-selected-value-price', option.getAttribute('data-price-increase'));

    // 移除错误信息
    document.getElementById(`${attrCode}-error`).classList.add('d-none');

    if (attrIncreasePrice === "1") {
        updatePriceDisplay();
    }

    // ### 如果是颜色选项，更新图片
    if (valueType === 'img') {
        const img_src = option.querySelector('img').getAttribute('src');
        console.log('img_src:', img_src);
        const filename = img_src.split('/').splice(-1).toString();
        console.log('filename:', filename);
        product_info['image'] = img_src;// preview only
    }

    // ### 如果是显示尺寸选项
    if (attrShowSizeChart === "1") {
        //显示尺码表
        const selectedValueCode = option.getAttribute('data-value-code');
        // 从 $size_charts 中获取尺码信息
        const sizeDetails = $size_charts[attrCode][selectedValueCode];

        const localChartContainer = document.getElementById(`${attrCode}-local-chart`);
        if (sizeDetails) {
            const localChartBody = document.getElementById(`${attrCode}-local-chart-body`);
            // 清空之前的尺码信息
            localChartBody.innerHTML = '';
            // 动态生成尺码详情表格行
            sizeDetails.forEach(detail => {
                // 合并 feet 和 inch，优先显示 feet
                const heightValue = detail.ft ? detail.ft : `${detail.inch} inch`;
                const row = document.createElement('tr');
                row.innerHTML = `
                            <td>${detail.attr_name}</td>
                            <td>${heightValue}</td>
                            <td>${detail.cm}</td>
                        `;
                localChartBody.appendChild(row);
            });
            // 显示尺码信息容器
            localChartContainer.classList.remove('d-none');
        } else {
            // 如果没有找到对应的尺码信息，隐藏尺码信息容器
            localChartContainer.classList.add('d-none');
        }
    }
}
document.addEventListener('DOMContentLoaded', () => {
    console.log('Bootstrap 已加载！');
    ////////////////////////////////侧栏
    try {
        const toggleButton = document.getElementById('toggle-aside');
        const offcanvasElement = document.getElementById('aside-menu');

        if (!toggleButton || !offcanvasElement) {
            throw new Error('缺少必要的 DOM 元素：#toggle-aside 或 #aside-menu');
        }

        const offcanvas = new Offcanvas(offcanvasElement);

        // 定义事件处理函数
        function handleToggle() {
            const isExpanded = toggleButton.getAttribute('aria-expanded') === 'true';
            toggleButton.setAttribute('aria-expanded', !isExpanded); // 更新状态
            offcanvas.toggle();
        }

        // 解绑旧的事件监听器（如果有）
        toggleButton.removeEventListener('click', handleToggle);

        // 绑定新的事件监听器
        toggleButton.addEventListener('click', handleToggle);
    } catch (error) {
        console.error('初始化 Offcanvas 时出错：', error);
    }
    ////////////////////////////////侧栏

    // $(".product-info-attr-js").on("click", "ul.product-info-value-list-js li", function() {
    // $('.sku-list-js').on('click', '.option', function () {
    //     // 获取当前点击的选项
    //     const option = $(this);
    //     // 调用处理选项点击事件的函数
    //     handleOptionClick(option);
    // });
    //事件委托    
    document.querySelectorAll(".sku-list-js").forEach(function (parentElement) {
        parentElement.addEventListener("click", function (e) {
            const optionElement = e.target.closest(".option");
            if (optionElement) {
                handleOptionClick(optionElement);
            }
        });
    });

    // // 获取所有选项
    // const options = document.querySelectorAll('.option');
    // // 绑定点击事件
    // options.forEach(option => {
    //     option.addEventListener('click', () => {
    //         handleOptionClick(option); // 处理选项点击事件
    //     });
    // });

    /////////////////////////////定制表单/////////////////////////////

    //定制表单 可能多个
    const customFormCheckboxs = document.querySelectorAll('.spu_custom_js');
    customFormCheckboxs.forEach(customFormCheckbox => {
        // ### 对应的相关属性：size etc.
        const relatedAttrCode = customFormCheckbox.getAttribute('data-related-attr-code');
        const relatedElements = document.querySelectorAll(`#${relatedAttrCode}-list li button`);

        // 单位系统
        const unitSelector = document.getElementById(`${relatedAttrCode}-unit-system`);
        // ### 相关属性值 受其他事件影响，需要动态获取
        const relatedValueElement = document.getElementById(`${relatedAttrCode}-input`);
        let relatedValueCode;
        // ### 相关属性值对应的尺码表
        const localChartContainer = document.getElementById(`${relatedAttrCode}-local-chart`);

        //定制表单容器 每个定制表单都有自己的容器
        const customElement = document.getElementById(`${relatedAttrCode}-custom-form-container`);

        // #########复选框 事件监听器
        customFormCheckbox.addEventListener('change', (event) => {
            //更新额外费用
            updatePriceDisplay();

            // 相关属性值
            relatedValueCode = relatedValueElement.getAttribute('value');
            if (event.target.checked) {// 选中
                // 移除错误信息
                document.getElementById(`${relatedAttrCode}-error`).classList.add('d-none');

                // 显示表单并动态渲染字段
                if (relatedValueCode) {
                    initCustomize(relatedAttrCode, unitSelector.value, relatedValueCode);
                    // 隐藏局部尺码表
                    localChartContainer.classList.add('d-none');
                }
                customElement.classList.remove('d-none');

                // 1 标识为定制
                relatedValueElement.setAttribute('data-is-custom', '1');

                // 2 置灰对应的尺码选项
                relatedElements.forEach(function (item) {
                    item.disabled = true;
                    item.style.opacity = '0.5'; // 置灰效果
                    item.setAttribute('aria-pressed', 'false');// 移除选中
                    item.setAttribute('aria-disabled', 'true'); // 提升无障碍访问性
                });

            } else {// 取消选中
                // 隐藏表单
                customElement.classList.add('d-none');
                if (relatedValueCode) {
                    // 显示局部尺码表
                    localChartContainer.classList.remove('d-none');
                }

                // 1 标识为非定制
                relatedValueElement.setAttribute('data-is-custom', '0');
                // 2 启用尺码列表项
                relatedElements.forEach(function (item) {
                    item.disabled = false;
                    item.style.opacity = ''; // 移除置灰效果
                    item.removeAttribute('aria-disabled'); // 恢复无障碍访问性

                    // 恢复选中状态
                    if (item.getAttribute('data-value-code') == relatedValueCode) {
                        item.setAttribute('aria-pressed', 'true');// 恢复选中
                    }
                });
            }

        });

        // ##########切换单位系统 事件监听器
        // 1 特殊的测量点处理,身高和体重
        const imperialHeight = document.getElementById('imperial-height');//
        const metricHeight = document.getElementById('metric-height');
        const weightUnitLabel = document.getElementById('weight-unit-label');
        // 2 通用的测量点处理
        const cus_units = customElement.querySelectorAll('.input-group-unit-js');
        unitSelector.addEventListener('change', () => {

            if (unitSelector.value === 'metric') {
                if (imperialHeight) {
                    imperialHeight.classList.add('d-none');
                    metricHeight.classList.remove('d-none');
                    weightUnitLabel.textContent = 'kg';
                }

                cus_units.forEach(function (element) {
                    element.textContent = 'cm';
                });

            } else {
                if (imperialHeight) {
                    imperialHeight.classList.remove('d-none');
                    metricHeight.classList.add('d-none');
                    weightUnitLabel.textContent = 'lb';
                }
                cus_units.forEach(function (element) {
                    element.textContent = 'in';
                });

            }

            if (relatedValueCode) {
                initCustomize(relatedAttrCode, unitSelector.value, relatedValueCode);
            }

        });

        // ##########输入框 focus blur 事件监听器
        const cus_inputs = customElement.querySelectorAll('input[type="number"]');
        cus_inputs.forEach(function (input) {
            input.addEventListener('focus', function () {
                this.classList.remove('is-invalid');
            });
            input.addEventListener('blur', function () {
                checkCustomInfo(this);
            });
        });

    });


    //tips modal
    const triggers = document.querySelectorAll('.measurement-trigger');
    const modalTitle = document.getElementById('measurementModalLabel');
    const modalImage = document.getElementById('modalImage');
    const modalDescription = document.getElementById('modalDescription');
    let activeTrigger = null; // Store the last clicked trigger button

    // 初始化 Modal 实例
    const measurementModalElement = document.getElementById('measurementModal');
    const measurementModal = new Modal(measurementModalElement);

    triggers.forEach(button => {
        button.addEventListener('click', function () {
            activeTrigger = this; // Save the clicked button
            const key = this.getAttribute('data-measurement'); // 获取数据键名，例如 "waist"
            const data = $size_custom_image[key]; // 从 JSON 中获取对应的数据

            if (!data) {
                return;
            }
            // 更新 Modal 内容
            modalTitle.textContent = data.local_img_title;

            // 设置图片（如果有的话）
            if (data.local_img && data.local_img.trim() !== '') {
                modalImage.src = data.local_img;
                modalImage.style.display = 'block';
            } else {
                modalImage.style.display = 'none';
            }

            // 插入描述（注意：这里的内容可能包含 <br> 标签）
            modalDescription.innerHTML = data.local_img_desc;

            // 显示 Modal
            measurementModal.show();

        });
    });

    // 监听模态框的隐藏事件，并在隐藏前将焦点返回到触发元素
    measurementModalElement.addEventListener('hidden.bs.modal', function () {
        if (activeTrigger) {
            //TODO 注：bootstrap5.3的示例文档里也是提示Blocked aria-hidden的问题：Blocked aria-hidden on an element because its descendant retained focus. The focus must not be hidden from assistive technology users. Avoid using aria-hidden on a focused element or its ancestor. Consider using the inert attribute instead, which will also prevent focus. For more details, see the aria-hidden section of the WAI-ARIA specification at https://w3c.github.io/aria/#aria-hidden.
            //这儿就先不处理这个问题了。
            console.log('Modal 隐藏，将焦点返回到触发元素');
            // setTimeout(() => {
            //     activeTrigger.focus();
            //     activeTrigger = null;
            // }, 10);

            activeTrigger.focus(); // 将焦点返回给最后点击的触发按钮
            activeTrigger = null; // 重置以避免潜在问题
        }
    });

    /////////////////////////////定制表单/////////////////////////////


    // 数量加减器
    const qtyInput = document.getElementById('quantity');
    const qtyPlus = document.querySelector('.qty-plus');
    const qtyMinus = document.querySelector('.qty-minus');

    qtyPlus.addEventListener('click', function () {
        let currentVal = parseInt(qtyInput.value);
        qtyInput.value = isNaN(currentVal) ? 1 : currentVal + 1;
    });

    qtyMinus.addEventListener('click', function () {
        let currentVal = parseInt(qtyInput.value);
        if (!isNaN(currentVal) && currentVal > 1) {
            qtyInput.value = currentVal - 1;
        }
    });

    //add to cart
    const addToCartButton = document.getElementById('add-to-cart');
    addToCartButton.addEventListener('click', function () {
        const data = getCartData();
        if (data.errors.length > 0) {
            scrollToElement(data.errors[0]);

            return;
        }
    });

});
